package com.irdstudio.apicenter.gateway.core.weixin;


import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import com.alibaba.fastjson.JSONObject;
import com.irdstudio.apicenter.gateway.core.jdbc.MaccsBaseDAO;
import com.irdstudio.apicenter.gateway.util.YcHttpClientUtil;
import com.irdstudio.apicenter.gateway.util.spring.BeanUtils;

/**
 * 微信工具类
 * 用于处理微信相关接口
 * @author fmf
 *
 */
public class WeiXinUtil {
	/* 文本日志记录对象(Logback对象) */
	private final static Logger logger = LoggerFactory
			.getLogger(WeiXinUtil.class);
	/**
	 * 获取微信令牌AccessToken(获取本地的)
	 * 
	 * @param appId
	 * @return
	 * @throws Exception 
	 */
	public static String getAccessToken(String appId) throws Exception{	
		String accessToken="";
		// 1.查询数据库记录的AccessToken
		MaccsBaseDAO jdbcDao = BeanUtils.getBean(MaccsBaseDAO.class);
		WeiXinAccessToken weiXinAccessToken = jdbcDao.findBean(WeiXinAccessToken.class,new Object[] { appId });
		accessToken=weiXinAccessToken.getAccessToken();
		// 2.校验AccessToken是否有效
		if(checkAccessToken(weiXinAccessToken)){
			//AccessToken无效，进行更新token操作
			accessToken=getWXAccessToken(appId);
		}
		return accessToken;
		
	}
	/**
	 * 去微信获取accessToken
	 * @param appId
	 * @return
	 * @throws Exception
	 */
	public static String getWXAccessToken(String appId) throws Exception{
		String url=getWXProp("TOKEN_URL")+"?corpid="+getWXProp("corpid")+"&corpsecret="+getWXProp("corpsecret");
		JSONObject json=YcHttpClientUtil.httpGet(url);
		logger.info("微信获取accessToken:\nURL="+url+"\nreturnJson="+json.toJSONString());
		MaccsBaseDAO jdbcDao = BeanUtils.getBean(MaccsBaseDAO.class);
		String accessToken=null;
		if(json!=null){
			if(json.get("access_token")!=null){
				accessToken=(String) json.get("access_token");
				//将AccessToken插入数据库
				String expiresIn=json.get("expires_in")+"";
				String updateSql="update wei_xin_access_token set ACCESS_TOKEN=? ,EXPIRES_IN=? where app_id=?";
				jdbcDao.update(updateSql,new Object[] { accessToken,expiresIn,appId });
			}else{
				throw new Exception("微信接口返回异常信息：errcode："+json.get("errcode")+"  errmsg:"+json.get("errmsg"));
			}
		}
		return accessToken;	
	}
	
	/**
	 * 检查是否需要去微信获取AccessToken，true 是需要重新获取AccessToken，false是不需要重新获取
	 * @param weiXinAccessToken
	 * @return
	 * @throws Exception 
	 */
	public static boolean checkAccessToken(WeiXinAccessToken weiXinAccessToken) throws Exception{
		String accessToken=weiXinAccessToken.getAccessToken();
		String getTime=weiXinAccessToken.getGetTime();//上一次获取AccessToken的时间
		String expiresIn=weiXinAccessToken.getExpiresIn();//AccessToken的时效，单位秒
		
		if("".equals(accessToken)||accessToken==null ){
			return true;
		}
		//AccessToken不为空，需校验其是否还有效，暂时不使用
		//1.格式化getTime
		/*SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
		
			Date d1=df.parse(getTime);//处理上一次获取AccessToken时间为Date格式
			Date d2=new Date();//当前系统时间
			long interval=d2.getTime()-d1.getTime();//两次时间的间隔
			long expiresInLong=Long.parseLong(expiresIn)*1000;//时效转换成long类型，并转换单位为毫秒
			if(interval<0 || interval> expiresInLong){
				//interval小于0，说明数据库记录的时间提前了，需要重新插入（理论不可能），interval> expiresInLong说明AccessToken超时了。
				return true;
			}*/
		return false;
	}
	
	/*
	 * 调用微信JS接口的临时票据
	 *  @param access_token 接口访问凭证
	 *  @return
	 */
	public static String getJsApiTicket(String appId) throws Exception{
		String access_token = getAccessToken(appId);;
		String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token="+access_token;
		String ticket = null;
		// 发起GET请求获取凭证
        JSONObject jsonObject = YcHttpClientUtil.httpGet(url);
        if (null != jsonObject) {
            try {
                ticket = jsonObject.getString("ticket");
            } catch (Exception e1) {
            	e1.printStackTrace();
            }
        }
		return ticket;
	}
	/**
	 * 获取用户的id，用于后续查询个人信息
	 * @param accessToken 微信令牌
	 * @param code 微信生成的code
	 * @return 返回JSON格式
	 * @throws Exception 
	 */
	public static JSONObject getUserId(String code,String appId) throws Exception{
		String accessToken=getAccessToken(appId);
		//拼装微信请求
		String url =getWXProp("USERID_URL")+"?access_token="+accessToken+"&code="+code;
		JSONObject returnJson= YcHttpClientUtil.httpGet(url);
		logger.info("获取用户id:\nURL = "+url+"\nreturnJson = "+returnJson.toJSONString());
		//42001： 请求超时     40014： access_token失效
		if((!"0".equals(returnJson.get("errcode").toString()) &&"42001".equals(returnJson.get("errcode").toString()) ) || "40014".equals(returnJson.get("errcode").toString())  ){
			//说明AccessToken失效了，重新获取tokenAccessToken
			String accessToken2=getWXAccessToken(appId);
			//重新拼接URL
			url=getWXProp("USERID_URL")+"?access_token="+accessToken2+"&code="+code;
			returnJson =YcHttpClientUtil.httpGet(url);
			logger.info("由于AccessToken失效，重新获取用户id:\nURL = "+url+"\nreturnJson = "+returnJson.toJSONString());
		}
		return returnJson;
	}
	/**
	 * 获取用户信息URL
	 * @param accessToken
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	public static JSONObject getUserInfo(String userId ,String appId ) throws Exception{
		String accessToken=getAccessToken(appId);
		String url =getWXProp("USERINFO_URL")+"?access_token="+accessToken+"&userid="+userId;
		JSONObject returnJson= YcHttpClientUtil.httpGet(url);
		logger.info("获取用户信息:\nURL = "+url+"\nreturnJson = "+returnJson.toJSONString());
		if((!"0".equals(returnJson.get("errcode").toString()) &&"42001".equals(returnJson.get("errcode").toString()) ) || "40014".equals(returnJson.get("errcode").toString()) ){
			//说明AccessToken失效了，重新获取tokenAccessToken
			String accessToken2=getWXAccessToken(appId);
			//重新拼接URL
			url=getWXProp("USERINFO_URL")+"?access_token="+accessToken2+"&userid="+userId;
			returnJson =YcHttpClientUtil.httpGet(url);
			logger.info("由于AccessToken失效，获取用户信息:\nURL = "+url+"\nreturnJson = "+returnJson.toJSONString());
		}
		return returnJson;	
	}
	
	/**
	 * 获取微信配置文件内容
	 * @param name 配置的名称
	 * @return 返回值
	 */
	public static String getWXProp(String name) {
        Resource resource = null;
        Properties props = null;
        String value = null;
        try {
            resource = new ClassPathResource("/weixin.properties");
            props = PropertiesLoaderUtils.loadProperties(resource);
            value= (String) props.get(name);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return value;
    }
	
	public static void main(String[] args) {
		try {
			System.out.println(WeiXinUtil.getWXAccessToken("3001"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
